home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / drdobbs / 1990 / 12 / crocker.asc < prev    next >
Text File  |  1990-11-15  |  14KB  |  351 lines

  1. _DESIGNING AN OSI TEST BED_
  2. by Kenneth L. Crocker and Michael T. Thompson
  3.  
  4. [LISTING ONE]
  5.  
  6. /*########## INITIALIZE INTERRUPTS, X.25 & TRANSPORT LAYER DATA #########*/
  7. /* AUTHOR: Michael T. Thompson, Planning Systems Inc. */
  8. /*          2-16-89 for Mitre Corp. (W85)  */
  9.  
  10. /* initialize interrupt routines */
  11.  
  12. #include <stdio.h>    /* MicroSoft "C" 5.1 " */
  13. #include <dos.h>    /* MS-DOS 3.30 */
  14. #include <ctype.h>
  15.  
  16. extern interrupt far clock();    /* Retix clock routine */
  17. extern interrupt far rcvdata();    /* Interrupt interface routine */
  18. extern buf_type bfh_head;
  19. extern unsigned char *rcvdat;  /* Common Receiver buffer pointer varible */
  20. extern buf_type rcvbuf;           /* Receiver User Data buffer pointer */
  21. extern int icnt, rbufcnt;      /* Number of pointers not used in Baddr Array */
  22. extern buf_type Baddr[];       /* Array of buffer pointers */
  23.  
  24. int xbufsiz=256;         /* Standard Buffer size */
  25. int number_of_buffers=30;    /* Total number of transmit and receive buffers */
  26.  
  27. /* ----- Primary system Initialization routine ----- */
  28. x25_init()
  29. {
  30. int i, tbufsiz, result;        /* Local varibles */
  31. tbufsiz = xbufsiz + 30;        /* Buffer size plus header data */
  32.  
  33.     _disable();       /* disable interrupts while initializing */
  34.     init_memory();        /* get available memory from DOS */
  35.     init_bufpool(&bpool,tbufsiz,number_of_buffers); /* setup buffer pool */
  36.     init_timers();       /* initialize system timers */
  37.     init_rcvbuf();       /* initialize receive buffers */
  38.    cominz();               /* initialize clock and I/O Interrupt routines */
  39.     _enable();       /* start interrupts backup */
  40. }
  41.  
  42. /*------------------- Initialize Receive Buffer Array --------------------*/
  43. init_rcvbuf()
  44. {
  45. int i;
  46.  
  47.     for(i=0;i<10;i++)        /* store pointers in buffer array */
  48.            Baddr[i] = getbuf(&bpool,xbufsiz+30); /* +30 for X.25 header info */
  49.     rbufcnt = 9;                    /* 0 to 9 = 10 buffers */
  50.     rcvbuf = Baddr[rbufcnt];     /* preallocate first buffer pointer */
  51.     Baddr[rbufcnt] = (buf_type) NULL;     /* clear the array pointer */
  52.     rcvdat = (char *)(BuffData(rcvbuf));  /* point to the user space */
  53.     icnt = 0;                     /* zero frame character count */
  54. }
  55.  
  56. /* ######################## COMINZ.C ########################## */
  57. /*   Initialize the Clock and Synchronous Interrupt routines    */
  58. cominz()
  59. {   
  60. unsigned intnum;
  61. unsigned int val;    /* local varibles */
  62.  
  63.     /* install MAC I/O driver */
  64.     intnum = 0x1c;            /* Clock interrupt vector */
  65.     _dos_setvect(intnum,clock);    /* setup new clock interrupt routine */
  66.     istart();             /* enable I/O interrupt processing */ 
  67.     intnum = 0x0c;            /* I/O interrupt vector */
  68.     _dos_setvect(intnum,rcvdata);    /* setup tx & rx interrupt routine */
  69.     val = inp(0x21);
  70.     outp(0x21,(val & 0xc7));    /* start irq 3, 4, & 5 */
  71. }
  72.  
  73. /* ++++++++++++++++ INITIALIZE SEALEVEL BOARD +++++++++++++++++ */
  74. istart()
  75. {
  76. unsigned char InitArray[50];    /* Allocate the size of the Init Array */
  77. int iCount;
  78.     /*------------------- Section # 1 ---------------------*/
  79.     InitArray[0]  = 9;
  80.     InitArray[1]  = 0xC0;    /* force hardware reset */
  81.     InitArray[2]  = 0;
  82.     InitArray[3]  = 0x00;
  83.     InitArray[4]  = 4;
  84.     InitArray[5]  = 0x20;    /* (SDLC) mode selected */
  85.     InitArray[6]  = 3;
  86.     InitArray[7]  = 0xC0;    /* rx 8 bits, sync char inhabit */
  87.     InitArray[8]  = 5;
  88.     InitArray[9]  = 0x61;    /* tx 8 bits */
  89.     InitArray[10] = 6;
  90.     InitArray[11] = 0;        /* For Mono-sync */
  91.     InitArray[12] = 7;
  92.     InitArray[13] = 0x7E;    /* sdlc sync character */
  93.     InitArray[14] = 10;
  94.     InitArray[15] = 0x80;    /* CRC set to inverted bit pattern */
  95.     InitArray[16] = 11;
  96.     InitArray[17] = 0;    /* for dte clock from RTxC pin */
  97.     InitArray[18] = 12;
  98.     InitArray[19] = 0xFE;    /* Low order baud rate value */
  99.     InitArray[20] = 13;
  100.     InitArray[21] = 00;        /* High order baud rate value */
  101.                 /*                        H  L  */
  102.                 /*               38400 = 00 3E  */
  103.                 /*               19200 = 00 7E  */  
  104.                 /* time constant: 9600 = 00 FE  */
  105.                 /*                4800 = 01 FE  */
  106.     InitArray[22] = 14;
  107.     InitArray[23] = 2;        /* gen enabled, gen source */
  108.     /*------------------- Section # 2 ---------------------*/
  109.     InitArray[24] = 14;
  110.     InitArray[25] = 3;        /* gen enabled, gen source */
  111.     InitArray[26] = 3;
  112.     InitArray[27] = 0xD9;    /* rx 8 bits, hunt mode, rx CRC, rx enabled */
  113.     InitArray[28] = 5;
  114.     InitArray[29] = 0x69;    /* tx 8 bits, tx enabled, tx CRC */
  115.     InitArray[30] = 0;
  116.     InitArray[31] = 0x80;    /* tx CRC gen */
  117.     InitArray[32] = 1;    /* int on all rx chars or special cond. */
  118.     InitArray[33] = 0x12;    /* enable tx interrupts */
  119.     /*------------------- Section # 3 ---------------------*/
  120.     InitArray[34] = 15;
  121.     InitArray[35] = 0x41;    /* tx underrun int enabled */
  122.     InitArray[36] = 0;
  123.     InitArray[37] = 0x30;    /* error reset */
  124.     InitArray[38] = 0;
  125.     InitArray[39] = 0x90;    /* tx CRC gen, reset ext/status int */
  126.     InitArray[40] = 0;
  127.     InitArray[41] = 0x90;    /* twice */
  128.     InitArray[42] = 1;    /* int on all rx chars or special cond. */
  129.     InitArray[43] = 0x12;    /* enable tx interrupts */
  130.     InitArray[44] = 9;
  131.     InitArray[45] = 8;    /* Master int enable */
  132.     InitArray[46] = 0;
  133.     InitArray[47] = 0xF0;    /* reset tx underrun, error reset */
  134.     InitArray[48] = 0;
  135.     InitArray[49] = 0x28;    /* reset tx int pending */
  136.  
  137.     for (iCount = 0; iCount < 50; iCount++)  
  138.         outp(0x239,InitArray[iCount]);    /* Output Data to SDLC Chip */
  139. }
  140.  
  141.  
  142. [LISTING TWO]
  143.  
  144. /********************************************************************
  145.  *  RCV2.C -- Interrupt Handler routine for use with the Sealevel   *
  146.  *  Systems synchronous communications board that uses preallocated *
  147.  *  buffers to Transmitt and Receive X.25 data frames.                *
  148.  ********************************************************************/
  149.  
  150. /* AUTHORS - Michael T. Thompson, Planning Systems Inc. and 
  151.  *           Ken Crocker, The MITRE Corporation    5/23/89
  152.  */
  153.  
  154. #include <stdio.h>    /* MicroSoft "C" 5.1 " */
  155. #include <dos.h>        /* MS-DOS 3.30 */
  156. #include <ctype.h>
  157.  
  158. /* RETIX OSI SOFTWARE COMMON HEADER FILES */
  159. #include "c:\retix\include\bufflib.h"
  160. #include "c:\retix\include\common.h"
  161. #include "c:\retix\include\system.h"
  162. #include "c:\retix\include\lapb.h"
  163. #include "c:\retix\include\address.h"
  164. #include "c:\retix\include\network.h"
  165. #include "c:\retix\include\x25.h"
  166.  
  167. extern buf_type MDATcon();     /* Data Confirm routine */
  168. extern struct sp_ent *mac;    /* Service provider table */
  169. extern xbufsiz;            /* Current TPDU buffer size */
  170. extern vpmidi();        /* MDATind Data Indiction routine */
  171.  
  172. unsigned char *rcvdat;          /* Pointer to received user data input buffer */
  173. buf_type rcvbuf;          /* Pointer to received buffer header */
  174. buf_type Baddr[10];          /* Array of allocated receive buffer pointers */
  175. int icnt, rbufcnt, fcnt;      /* Receiver and Transmitter counters */
  176. int fsize;              /* Size of Transmit Frame */
  177. char *frame;              /* Temporary pointer to Transmit frame */
  178.  
  179. /************************** RCVDATA.C ****************************
  180.  *          Interrupt Driven Receiver and Transmitter            *
  181.  *  RECEIVER: On the receive side an array of buffer pointers is *
  182.  *  allocated in the x251t.c initialization Routine. The first   *
  183.  *  buffer is preassigned to the receive routine and then that   *
  184.  *  buffer can be written to by the interrupt routine. When the  *
  185.  *  last character of the frame is received the MDATind (vpmidi) *
  186.  *  routine is called and the new buffer is put on the queue for *
  187.  *  processing later. After that we get the address of another   *
  188.  *  preallocated buffer from the array and setup the proper      *
  189.  *  pointers.                                                    *
  190.  *****************************************************************/
  191.  
  192. void interrupt cdecl rcvdata()
  193. {
  194. unsigned int c, c1, delay;     /* local varibles */
  195. _enable();            /* enable interrupts */
  196.  
  197. /* check if this is an error, a receive or a transmitt interrupt */
  198. outp(0x239,3);
  199. delay = 0;         /* allow time for the register to setup */
  200.    if(((c = inp(0x239)) & 0x30) != 0)  /* if not an error continue */
  201.     {
  202.           if((c & 0x20) != 0)      /* if not receive interrupt continue */
  203.         {
  204.  
  205.     /******** RECEIVE DRIVER *********/
  206.     /*   we must have receive data   */
  207.     /*********************************/
  208.     rcvdat[icnt++] = inp(0x238);     /* get character and store it */
  209.     outp(0x239,1);
  210.     delay = 0;
  211.     if(((c1 = inp(0x239)) & 0x80) != 0)    /* check for end of frame */
  212.     {        
  213.         if((c1 & 0x70) == 0)  /* check for a valid CRC */
  214.         {    /* must be OK */
  215.           if(icnt > 3)
  216.           { 
  217.             rcvdat[icnt-2] = 0;
  218.             BuffAdjust(rcvbuf,((xbufsiz+30)-(icnt-2)));
  219.                /* reajust buffer size for lapb */
  220.             vpmidi(rcvbuf,mac);
  221.               /* send MDATind to service user */
  222.             icnt = 0;
  223.             while(Baddr[--rbufcnt] == (buf_type) NULL);
  224.               /* Find an unused buffer pointer */
  225.             rcvbuf = Baddr[rbufcnt];
  226.               /* got a new receive buffer pointer */
  227.             Baddr[rbufcnt] = (buf_type) NULL;
  228.               /* clear buffer pointer from array */
  229.             rcvdat = (char *)(BuffData(rcvbuf));
  230.               /* setup receive data pointer */
  231.               /* check for a transmit interrupt pending */
  232.             if((c & 0x10) == 0)
  233.               goto ENDINT;  /* no interrupt so end */
  234.           /* found transmit interrupt pending so send it */
  235.             goto TXINT; 
  236.           }
  237.           /* frame is to short so go to error reset */
  238.           goto ERRRES;         
  239.     }
  240.     /* We got a BAD CRC */
  241.     goto ERRRES;    /* goto error reset */
  242.      }
  243.     /* not end of frame so check for a transmit interrupt pending */
  244.     if((c & 0x10) == 0)
  245.     /* no transmit interrupt so end interrupt routine */
  246.     goto ENDINT;
  247.         }
  248.  
  249. TXINT:/************************ TRANSMIT DRIVER *****************************/
  250.       /* After we have determined that we have received a transmit interrupt*/ 
  251.       /* we check to see if we are at end of frame by checking its size. If */
  252.       /* not, then we send out character pointed  at by frame pointer and   */
  253.       /* then end the interrupt. If we are at end of frame, we clear frame  */
  254.       /* counter and reset the transmit interrupt flag.                     */
  255.       /**********************************************************************/
  256.         
  257.         if(fsize > 0)      /* are at the end of the frame ? */
  258.         {
  259.         fsize--;                    /* decrement frame size */
  260.         outp(0x238,frame[fcnt++]);     /* NO - send character */
  261.         goto ENDINT;                    /* end the interrupt routine */
  262.         }
  263.         outp(0x239,0);       /* must be at the end of the frame */
  264.         fcnt = 0;       /* clear the frame count */
  265.         outp(0x239,0x28); /* reset transmit interrupts */
  266.         goto ENDINT;      /* end the interrupt routine */ 
  267.     }
  268. ERRRES:
  269.    outp(0x239,0);      /* error reset */
  270.    icnt = 0;          /* reuse the same buffer */
  271.    outp(0x239,0x30);
  272. ENDINT:
  273.    outp(0x20,0x20);         /* End of interrupt report */
  274.     return;
  275. }
  276.  
  277. /******************************** MDATreq() **********************************
  278.  *  MDATreq: Transmit LAPB output requests. When a buffer is ready to be     * 
  279.  *  transmitted, that buffer is sent to MDATreq routine where we check to see* 
  280.  *  if data is currently being transmitted. If it is, we return to calling   * 
  281.  *  routine and try again later. If no data is being transmitted, we check   *
  282.  *  transmit buffer register of synchronous controller chip to see if it is  * 
  283.  *  empty so that when it is, we can send out first character of frame. When * 
  284.  *  we can send out a character the pointers and counters are setup and      *
  285.  *  first character is sent. After first character is sent, buffer is removed*
  286.  *  from outbound queue and a second character is sent to help with system   * 
  287.  *  timing. At this point, interrupt driver will take over and continue to   *
  288.  *  send remaining data until last byte of frame is delivered along with     *
  289.  *  frames CRC.                                                              *
  290.  *****************************************************************************/
  291.  
  292. void MDATreq (msdu)
  293. buf_type msdu;            /* Transmitt buffer pointer */
  294. {
  295. int rval, delay;       /* local varibles */
  296.     if(fsize != 0)       /* if we are still transmitting a frame return */
  297.         return;
  298.     outp(0x239,0);
  299.     fcnt=0;
  300.     while (((rval = inp(0x239)) & 4) == 0);  /* test for buffer empty */
  301.  
  302.     frame = (char *)(BuffData(msdu));   /* get pointer to user buffer */
  303.     fsize = (BuffSize(msdu)-1);        /* get size minus first char */
  304.     QRemove(msdu);                /* remove buffer from queue */
  305.     delay=0;
  306.     outp(0x238,frame[fcnt++]);          /* send first byte of frame */
  307.  
  308.     msdu=(buf_type)MDATcon(msdu,mac);   /* and confirm the buffer */
  309.     while (((rval = inp(0x239)) & 4) == 0);  /* test for buffer empty */
  310.  
  311.     fsize--;                /* decrement frame size */
  312.     outp(0x238,frame[fcnt++]);        /* send second byte of frame */
  313.  
  314.     outp(0x239,0);    
  315.     delay = 0;    
  316.     outp(0x239,0xC0);             /* process end of frame CRC */
  317.  
  318.     return;
  319. }
  320.  
  321.  
  322. [LISTING THREE]
  323.  
  324. /****************************************************************************
  325.  *  Poll timer queue for any expired timers. Next check to see if there is  * 
  326.  *  any X.25 traffic to be moved on Inbound or Outbound packet queue. The   *
  327.  *  last process we check is if Baddr Array is low on preallocated receive  *
  328.  *  buffers that are used by RCV2.C Interrupt Handler.                      *
  329.  ****************************************************************************/
  330. /* AUTHOR - Michael T. Thompson, Planning Systems Inc.  5/23/89  */
  331.  
  332. poldat()
  333. {
  334.     int i;    /* index varible */
  335.     do_timer_queue();  /* Test for expaired timers */
  336.     do_lapb_queue();   /* Check for X.25 Traffic */
  337.     if(rbufcnt < 4)       /* replenish array if less than four pointers */
  338.     {
  339.         for(i=0;i<9;i++)    /* check all receive buffers */
  340.         {    
  341.            if(Baddr[i] == NULL)    /* If Null, pointer has been used */
  342.            {    /* Get new buffer pointer & assign it to the array */
  343.             Baddr[i] = getbuf(&bpool,xbufsiz+30); 
  344.             rbufcnt++;            /* Increment buffer count */
  345.            }
  346.         }
  347.     }  
  348. }    /* END OF POLDAT */
  349.  
  350.  
  351.